package com.ruoyi.common.utils;

import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class EnFiUtil {

    public static ThreadPoolExecutor getTheadPool() {
        return EnFiUtil.getTheadPool(5);
    }

    public static HttpServletRequest getRequest(){
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        return request;
    }
    public static HttpServletResponse getResponse(){
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = servletRequestAttributes.getResponse();
        return response;
    }
    public static ThreadPoolExecutor getTheadPool(Integer corePoolSize) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, //核心线程数
                20, //最大线程数
                60, TimeUnit.SECONDS, //每个线程最大运行时间 ,和时间单位
                new LinkedBlockingQueue<Runnable>(10000));//线程存放队列 ，有界队列容量1万
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        RequestContextHolder.setRequestAttributes(servletRequestAttributes, true);//设置子线程共享
        return threadPoolExecutor;
    }


    public static Boolean waitThreadPoolCompleted(ThreadPoolExecutor threadPoolExecutor) {
        return EnFiUtil.waitThreadPoolCompleted(threadPoolExecutor, "");
    }

    public static Boolean waitThreadPoolCompleted(ThreadPoolExecutor threadPoolExecutor, String message) {
        return EnFiUtil.waitThreadPoolCompleted(threadPoolExecutor, "", () -> {});
    }

    public static Boolean waitThreadPoolCompleted(ThreadPoolExecutor threadPoolExecutor, String message, ExecuteOperation operation) {
        threadPoolExecutor.shutdown();
        try {
            while (true) {
                if (threadPoolExecutor.isTerminated()) {
                    System.out.println("===========================================================================");
                    System.out.println(message + " 全部线程执行完毕 ");
                    System.out.println("===========================================================================");
                    operation.execute();
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

//    public static String getUserName() {
//        return JwtUtil.getUserNameByToken(getRequest());
//    }

    private static HashMap<String, String> LoginUser;
    public static HashMap<String, String> getLoginUser() {
        if (LoginUser == null) {
            synchronized (EnFiUtil.class) {
                //进入同步代码块后，再检查一次，如果仍是null，才创建实例
                if (LoginUser == null) {
                    LoginUser = new HashMap<String, String>();
                }
            }
        }
        return LoginUser;
    }

//    public static String sign(String username ,String password){
//        EnFiUtil.getLoginUser().put(username,password);
//        String token = JwtUtil.sign(username, password);
//        return token;
//    }

    public interface ExecuteOperation {
        void execute();
    }

    /**
     * 对象属性转换为字段  例如：userName to user_name
     *
     * @param property 字段名
     * @return
     */
    public static String propertyToField(String property) {
        if (null == property) {
            return "";
        }
        char[] chars = property.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (char c : chars) {
            if (CharUtils.isAsciiAlphaUpper(c)) {
                sb.append("_" + org.apache.commons.lang3.StringUtils.lowerCase(CharUtils.toString(c)));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 字段转换成对象属性 例如：user_name to userName
     *
     * @param field
     * @return
     */
    public static String fieldToProperty(String field) {
        if (null == field) {
            return "";
        }
        char[] chars = field.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];
            if (c == '_') {
                int j = i + 1;
                if (j < chars.length) {
                    sb.append(StringUtils.upperCase(CharUtils.toString(chars[j])));
                    i++;
                }
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
    public static String timeMillisToDateString(String timeMillis){
        Date date = new Date(Long.parseLong(timeMillis));
        SimpleDateFormat simpleDateFormat = getSimpleDateFormat();
        String format = simpleDateFormat.format(date);
        return format;
    }
    public static String getNowDateString(){
        SimpleDateFormat simpleDateFormat = getSimpleDateFormat();
        String format = simpleDateFormat.format(new Date());
        return format;
    }
    public static String getDateString(Date date){
        SimpleDateFormat simpleDateFormat = getSimpleDateFormat();
        String format = simpleDateFormat.format(date);
        return format;
    }

    private static HashMap<String, String> projectStatusMap;

    public static HashMap<String, String> getProjectStatusMap() {
        if (projectStatusMap == null) {
            synchronized (EnFiUtil.class) {
                //进入同步代码块后，再检查一次，如果仍是null，才创建实例
                if (projectStatusMap == null) {
                    projectStatusMap = new HashMap<String, String>() {{
                        put("进行", "在执行");
                        put("完工", "在执行");
                        put("终止", "已完成");
                        put("暂停", "已完成");
                        put("结束", "已完成");
                    }};
                }
            }
        }
        return projectStatusMap;
    }

    private static SimpleDateFormat simpleDateFormat;

    public static SimpleDateFormat getSimpleDateFormat() {
        if (simpleDateFormat == null) {
            synchronized (EnFiUtil.class) {
                //进入同步代码块后，再检查一次，如果仍是null，才创建实例
                if (simpleDateFormat == null) {
                    simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                }
            }
        }
        return simpleDateFormat;
    }


    public static <O> O dynamicBeanAddPProperty(HashMap<String,Object> map,O object){

        try {
            Object o = new ClassUtil().dynamicClass(object, new HashMap<String, Object>() {{
                map.forEach((s, o) -> {
                    try {
                        put(s, Class.forName(o.getClass().getName()));
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                });
            }}, map);
            return (O) o;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  object;
    }

//    public static Object mapToObject(Map<String, Object> map, Class<?> beanClass) throws Exception {
//        if (map == null)
//            return null;
//
//        Object obj = beanClass.newInstance();
//
//        org.apache.commons.beanutils.BeanUtils.populate(obj, map);
//
//        return obj;
//    }

    /**
     * 对象转Map
     * @param object
     * @return
     */
    public static Map<String, Object> objectToMap(Object object) throws IllegalAccessException {
        Map<String, Object> map = new HashMap<String, Object>(){{
            Field[] fields = object.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                put(field.getName(), field.get(object));
            }
        }};
        return map;
    }



}

